package com.zx;

import org.junit.Test;
import java.util.stream.Stream;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import java.util.ArrayList;
import java.util.function.Predicate;

// 该类用于演示 Stream API 的基本用法
public class StreamDemo {

    public static void main(String[] args) {

        // 创建并初始化一个字符串列表
        List<String> list = new ArrayList<>();
        list.add("张怀义");
        list.add("张之维");
        list.add("李楠");
        list.add("杨颜");
        list.add("陈希");
        list.add("白永祥");
        list.add("张斯科");
        list.add("周星驰");
        list.add("林正英");

        // 用传统方式筛选姓张的名字
        List<String> list1 = new ArrayList<>();
        list.forEach(s -> {
            if (s.startsWith("张")) {
                list1.add(s);
            }
        });

        // 用传统方式进一步筛选出长度为3的名字
        List<String> list2 = new ArrayList<>();
        list1.forEach(s -> {
            if (s.length() == 3) {
                list2.add(s);
            }
        });

        // 输出筛选后的结果
        list2.forEach(System.out::println);

        System.out.println("---------------------------------------------");

        // 使用Stream API直接完成筛选姓张且长度为3的名字
        list.stream()
                .filter(s -> s.startsWith("张"))
                .filter(s -> s.length() == 3)
                .forEach(System.out::println);

        // 调用 test1 方法
        StreamDemo demo = new StreamDemo();
        demo.test1();
        demo.test2();
        demo.test3();
    }

    @Test
    public void test1() {
        System.out.println("---------------------------------------------");
        List<Integer> math = new ArrayList<>();
        math.add(1);
        math.add(2);
        math.add(3);
        math.add(4);
        math.add(5);
        math.add(6);
        math.add(7);
        math.add(8);
        math.add(9);
        math.add(10);
        math.add(11);
        math.add(12);
        math.add(13);
        math.add(14);
        math.add(15);
        math.add(16);
        math.add(17);
        math.add(18);
        math.add(19);
        math.add(20);

        List<Integer> evenNumbers = math.stream()
                .filter(t -> t % 2 == 0)
                .collect(Collectors.toList());

        // 输出筛选后的偶数结果
        System.out.println(evenNumbers);
    }

    @Test
    public void test2() {
        System.out.println("---------------------------------------------");
        List<String> list = new ArrayList<>();
        list.add("张三,23");
        list.add("李四,25");
        list.add("王五,24");

        Map<String, Integer> filteredMap = list.stream().filter(s -> {
            String[] arr = s.split(",");

            int age = Integer.parseInt(arr[1]);

            return age >= 24;
        }).collect(Collectors.toMap(s -> s.split(",")[0],
                s -> Integer.parseInt(s.split(",")[1])));


        filteredMap.forEach((k, v) -> {
            System.out.println(k + ":" + v);
        });
    }

    @Test
    public void test3() {
        System.out.println("---------------------------------------------");
        List<String> list = new ArrayList<>();
        // 男演员
        list.add("张怀义");
        list.add("张之维");
        list.add("周星驰");
        list.add("张斯科");
        list.add("林夕");

        List<String> list2 = new ArrayList<>();
        // 女演员
        list2.add("杨幂");
        list2.add("杨紫");
        list2.add("高圆圆");
        list2.add("赵丽颖");
        list2.add("赵雅之");
        list2.add("张丽娜");

        // 使用 Predicate 和 limit 限制男演员的数量
        Stream<String> stream1 = list.stream().filter(new Predicate<String>() {
            @Override
            public boolean test(String s) {
                return s.length() == 3; // 过滤出长度为3的名字
            }
        }).limit(2); // 限制输出前两个

        // 使用 Predicate 和 skip 跳过第一个女演员
        Stream<String> stream2 = list2.stream().filter(new Predicate<String>() {
            @Override
            public boolean test(String s) {
                return s.startsWith("杨");
            }
        }).skip(1); // 跳过第一个结果

        // 合并两个流并打印结果
        Stream.concat(stream1, stream2).forEach(System.out::println);
    }
}
